package com.koushikdutta.async.http;

import android.net.Uri;
import android.text.TextUtils;
import com.koushikdutta.async.AsyncSSLSocket;
import com.koushikdutta.async.AsyncSSLSocketWrapper;
import com.koushikdutta.async.AsyncSSLSocketWrapper.HandshakeCallback;
import com.koushikdutta.async.AsyncSocket;
import com.koushikdutta.async.DataSink;
import com.koushikdutta.async.LineEmitter;
import com.koushikdutta.async.LineEmitter.StringCallback;
import com.koushikdutta.async.Util;
import com.koushikdutta.async.callback.CompletedCallback;
import com.koushikdutta.async.callback.ConnectCallback;
import com.koushikdutta.async.http.libcore.RawHeaders;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;

public class AsyncSSLSocketMiddleware extends AsyncSocketMiddleware {
    protected List<AsyncSSLEngineConfigurator> engineConfigurators = new ArrayList();
    protected HostnameVerifier hostnameVerifier;
    protected SSLContext sslContext;
    protected TrustManager[] trustManagers;

    public AsyncSSLSocketMiddleware(AsyncHttpClient client) {
        super(client, "https", 443);
    }

    public void setSSLContext(SSLContext sslContext) {
        this.sslContext = sslContext;
    }

    public SSLContext getSSLContext() {
        return this.sslContext != null ? this.sslContext : AsyncSSLSocketWrapper.getDefaultSSLContext();
    }

    public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
        this.hostnameVerifier = hostnameVerifier;
    }

    protected SSLEngine createConfiguredSSLEngine(String host, int port) {
        SSLEngine sslEngine = getSSLContext().createSSLEngine();
        for (AsyncSSLEngineConfigurator configurator : this.engineConfigurators) {
            configurator.configureEngine(sslEngine, host, port);
        }
        return sslEngine;
    }

    protected HandshakeCallback createHandshakeCallback(final ConnectCallback callback) {
        return new HandshakeCallback() {
            public void onHandshakeCompleted(Exception e, AsyncSSLSocket socket) {
                callback.onConnectCompleted(e, socket);
            }
        };
    }

    protected void tryHandshake(ConnectCallback callback, AsyncSocket socket, Uri uri, int port) {
        AsyncSSLSocketWrapper.handshake(socket, uri.getHost(), port, createConfiguredSSLEngine(uri.getHost(), port), this.trustManagers, this.hostnameVerifier, true, createHandshakeCallback(callback));
    }

    protected ConnectCallback wrapCallback(ConnectCallback callback, Uri uri, int port, boolean proxied) {
        final boolean z = proxied;
        final ConnectCallback connectCallback = callback;
        final Uri uri2 = uri;
        final int i = port;
        return new ConnectCallback() {
            public void onConnectCompleted(Exception ex, final AsyncSocket socket) {
                if (ex != null) {
                    connectCallback.onConnectCompleted(ex, socket);
                } else if (z) {
                    RawHeaders connect = new RawHeaders();
                    connect.setStatusLine(String.format("CONNECT %s:%s HTTP/1.1", new Object[]{uri2.getHost(), Integer.valueOf(i)}));
                    Util.writeAll((DataSink) socket, connect.toHeaderString().getBytes(), new CompletedCallback() {
                        public void onCompleted(Exception ex) {
                            if (ex != null) {
                                connectCallback.onConnectCompleted(ex, socket);
                                return;
                            }
                            LineEmitter liner = new LineEmitter();
                            liner.setLineCallback(new StringCallback() {
                                String statusLine;

                                public void onStringAvailable(String s) {
                                    if (this.statusLine == null) {
                                        this.statusLine = s;
                                        if (this.statusLine.length() > 128 || !this.statusLine.contains("200")) {
                                            socket.setDataCallback(null);
                                            socket.setEndCallback(null);
                                            connectCallback.onConnectCompleted(new IOException("non 200 status line"), socket);
                                            return;
                                        }
                                        return;
                                    }
                                    socket.setDataCallback(null);
                                    socket.setEndCallback(null);
                                    if (TextUtils.isEmpty(s.trim())) {
                                        AsyncSSLSocketMiddleware.this.tryHandshake(connectCallback, socket, uri2, i);
                                    } else {
                                        connectCallback.onConnectCompleted(new IOException("unknown second status line"), socket);
                                    }
                                }
                            });
                            socket.setDataCallback(liner);
                            socket.setEndCallback(new CompletedCallback() {
                                public void onCompleted(Exception ex) {
                                    if (!socket.isOpen() && ex == null) {
                                        ex = new IOException("socket closed before proxy connect response");
                                    }
                                    connectCallback.onConnectCompleted(ex, socket);
                                }
                            });
                        }
                    });
                } else {
                    AsyncSSLSocketMiddleware.this.tryHandshake(connectCallback, socket, uri2, i);
                }
            }
        };
    }
}
